oo::class create Linum {
    superclass Plugin
    variable Linum RenamedPadWidget PadWidget MultiYScroll

    constructor {multiYScroll} {
        set MultiYScroll $multiYScroll
        set RenamedPadWidget _[set [info object namespace $multiYScroll]::PadWidget]
        set PadWidget [string trimleft $RenamedPadWidget _]
        set Linum ${PadWidget}Linum
        text $Linum -width 1 -bg #585858 -fg #E6E6E6 -bd 0 -cursor arrow
        pack $Linum -side left -fill y
        $Linum tag configure R -justify right
        $Linum insert end 1 R
        $Linum configure -state disable

        my scroll
    }

    method scroll {} {
        $MultiYScroll appendWidget $Linum
    }

    method updateLinum {args} {
        my withUnlock $Linum {
            set padNum [expr [lindex [split [$RenamedPadWidget index end] .] 0]-1]
            set linumNum [expr [lindex [split [${PadWidget}Linum index end] .] 0]-1]
            if {$linumNum < $padNum} {
                incr linumNum
                while {$linumNum <= $padNum} {
                    ${PadWidget}Linum insert end "\n$linumNum" R
                    incr linumNum
                }
            } else {
                ${PadWidget}Linum delete "$padNum.0 +1l linestart" end
            }
            ${PadWidget}Linum configure -width [string length $padNum]
        }
    }

    method getPluginEvents {} {
        return {
            {afterInsert updateLinum}
            {afterDelete updateLinum}
            {afterReplace updateLinum}
        }
    }

    destructor {
        catch {
            # MultiYScroll may have been destroyed for the reason of exit app
            $MultiYScroll removeWidget $Linum
        }
        destroy $Linum
    }
}